<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="zh" xml:lang="zh" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Guideline: 编写自动化测试脚本</title>
<meta name="uma.type" content="Guideline">
<meta name="uma.name" content="programming_automated_test_scripts">
<meta name="uma.presentationName" content="编写自动化测试脚本">
<meta name="element_type" content="other">
<meta name="filetype" content="description">
<meta name="role" content="">
<link rel="StyleSheet" href="./../../../css/default.css" type="text/css">
<script src="./../../../scripts/ContentPageResource.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/ContentPageSection.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/ContentPageSubSection.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/ContentPageToolbar.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/contentPage.js" type="text/javascript" language="JavaScript"></script><script type="text/javascript" language="JavaScript">
					var backPath = './../../../';
					var imgPath = './../../../images/';
					var nodeInfo=null;
					contentPage.preload(imgPath, backPath, nodeInfo,  '', false, false, false);
				</script>
</head>
<body>
<div id="breadcrumbs"></div>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td valign="top"><a name="Top"></a>
<div id="page-guid" value="6.202272769754314E-305"></div>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td class="pageTitle" nowrap="true">Guideline: 编写自动化测试脚本</td><td width="100%">
<div align="right" id="contentPageToolbar"></div>
</td><td width="100%" class="expandCollapseLink" align="right"><a name="mainIndex" href="./../../../index.htm"></a><script language="JavaScript" type="text/javascript" src="./../../../scripts/treebrowser.js"></script></td>
</tr>
</table>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="pageTitleSeparator"><img src="./../../../images/shim.gif" alt="" title="" height="1"></td>
</tr>
</table>
<div class="overview">
<table width="97%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="50"><img src="./../../../images/guidance.gif" alt="" title=""></td><td>
<table class="overviewTable" border="0" cellspacing="0" cellpadding="0">
<tr>
<td valign="top">本指南描述有效的自动化测试脚本部署的原则。</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="sectionHeading">Relationships</div>
<div class="sectionContent">
<table class="sectionTable" border="0" cellspacing="0" cellpadding="0">
<tr valign="top">
<th class="sectionTableHeading" scope="row">Related Elements</th><td class="sectionTableCell">
<ul>
<li>
<a href="./../../../rup/domains/test_FBB424F8.html" guid="_SPvXcN7IEdm8G6yT7-Wdqw">测试</a>
</li>
<li>
<a href="./../../../rup/workproducts/rup_test_script_2140080.html" guid="{293A9F23-BB20-4993-AABE-76C1E8E1A589}">测试脚本</a>
</li>
</ul>
</td>
</tr>
</table>
</div>
<div class="sectionHeading">Main Description</div>
<div class="sectionContent">
<table class="sectionTable" border="0" cellspacing="0" cellpadding="0">
<tr valign="top">
<td class="sectionTableSingleCell"><a id="Top" name="Top"></a><a key="测试脚本（test script）" text="指南" name="XE_test_script__guidelines_for" id="XE_test_script__guidelines_for" class="index"></a> 
<h3>
    <a id="StructureOfTestScripts" name="StructureOfTestScripts">测试脚本的结构</a>
</h3>
<p>
    为了增加测试脚本的可维护性和可重用性，应在实现它们之前先构造它们。您可能将发现有一些将在若干测试脚本中出现的操作。确定这些操作应成为一个目标，使您可以重用它们的实现。
</p>
<p>
    例如，您可能有这样的测试脚本，它们是您可以对一条记录执行的不同操作的组合。这些测试脚本可以是一条记录的添加、修改和删除操作的组合：
</p>
<ul>
    <li>
        添加、修改、删除（很明显的一个）
    </li>
    <li>
        添加、删除、修改
    </li>
    <li>
        添加、删除、添加、删除……
    </li>
    <li>
        添加、添加、添加……
    </li>
</ul>
<p>
    如果您将这些操作作为分开的测试脚本确定和实现，并在其他测试脚本中重用它们，您将可以实现更高级别的重用。
</p>
<p>
    另一个目标将是以下面的方式构造测试脚本，即目标软件中的一个更改可以导致测试脚本中本地化的并可以控制的更改。这将使您的测试脚本对目标软件中的更改更有弹性。例如，假设软件的登录部分已更改。对于穿过登录部分的所有测试用例，仅与登录相关的测试脚本必须更改。
</p>
<h3>
    <a id="RecordingTechnique" name="RecordingTechnique">记录技术</a> <a key="测试脚本的记录技术（recording techniques for test scripts）" name="XE_recording_techniques_for_test_scripts" id="XE_recording_techniques_for_test_scripts" class="index"></a><a key="测试脚本（test script）" text="记录技术" name="XE_test_script__recording_techniques" id="XE_test_script__recording_techniques" class="index"></a>
</h3>
<p>
    要实现测试脚本的更高维护性，您应以下面的方式记录它们，即最不易受测试目标中的更改的影响。例如，对于填写对话框字段的测试脚本，有一些关于如何从一个字段转到下一个字段的选项：
</p>
<ul>
    <li>
        使用 TAB 键
    </li>
    <li>
        使用鼠标
    </li>
    <li>
        使用键盘加速键
    </li>
</ul>
<p>
    在这些选项中，其中一些比另一些更容易受到设计更改的影响。如果在屏幕上插入一个新的字段，则 TAB
    键方法将不可靠。如果重新指定了加速键，它们将不会提供良好的记录。如果鼠标用于确定一个字段的方法容易发生更改，这可能也不是一个可靠的方法。但是，一些测试自动化工具具有测试脚本记录器，可以指示它们通过更可靠的方法确定该字段，例如由开发工具（PowerBuilder、SQLWindows
    或 Visual Basic）分配的对象名称。以这种方式，一个记录的测试脚本不会受到对用户界面的小更改（例如，布局更改、字段标签更改、格式化更改等）的影响。
</p>
<h3>
    <a id="Data-DrivenTesting" name="Data-DrivenTesting">数据驱动的测试</a> <a key="数据驱动测试" name="XE_data-driven_testing" id="XE_data-driven_testing" class="index"></a><a key="测试脚本（test script）" text="数据驱动测试" name="XE_test_script__data-driven_testing" id="XE_test_script__data-driven_testing" class="index"></a>
</h3>
<p>
    许多测试脚本涉及在一个给定的数据输入屏幕中输入若干组字段数据以检查字段验证功能、错误处理等。过程步骤是相同的；只有数据不同。无需为每组输入数据都记录一个测试脚本，而只应进行单独一次记录，然后进行修改以处理多个数据集。例如，由于无效数据而生成相同错误的所有数据集可以共享同一记录的测试脚本。该测试脚本被修改为将数据作为变量信息处理、从文件或其他外部来源读取数据集以及在所有相关数据集中循环。
</p>
<p>
    如果开发了测试脚本或测试代码以在输入数据集和输出数据集中循环，则必须建立这些数据集。这些数据集通常使用的格式是文本文件中逗号分隔字段的记录。此格式易于从测试脚本和测试代码中读取，并易于创建和维护。
</p>
<p>
    多数数据库和电子表格软件包可以生成逗号分隔的文本输出。使用这些软件包组织或捕获数据集有两个重要的好处。首先，它们为输入和编辑数据提供了比仅使用文本编辑器或字处理程序更结构化的环境。其次，多数具有查询现有数据库并捕获返回数据的能力，实现了一种从现有来源中抽取数据集的容易的方式。
</p>
<h3>
    <a id="ErrorHandling" name="ErrorHandling">错误处理</a> <a key="错误处理（error handling）" text="在测试中进行错误处理" name="XE_error_handling__in_testing" id="XE_error_handling__in_testing" class="index"></a>
</h3>
<p>
    记录的测试脚本在其执行时是连续的。没有任何分支点。测试脚本中健壮的错误处理需要额外的逻辑以响应错误条件。当错误发生时可以采用的决策逻辑包括：
</p>
<ul>
    <li>
        分支到一个不同的测试脚本。
    </li>
    <li>
        调用试图清除错误条件的脚本。
    </li>
    <li>
        退出该脚本并启动下一个脚本。
    </li>
    <li>
        退出该脚本和该软件，重新启动，并从已失败的脚本之后的下一个测试脚本重新开始测试。
    </li>
</ul>
<p>
    每项错误处理技术都需要向测试脚本添加程序逻辑。这种逻辑应尽可能多地限制在控制低级测试脚本的先后顺序的高级测试脚本中。这允许低级测试脚本完全从记录中创建。
</p>
<h3>
    <a id="TestScriptSynchronizationAndScheduling" name="TestScriptSynchronizationAndScheduling">测试脚本同步与时间安排</a> <a key="测试脚本（test script）" text="同步和进度安排" name="XE_test_script__synchronization_and_scheduling_of" id="XE_test_script__synchronization_and_scheduling_of" class="index"></a>
</h3>
<p>
    当进行压力测试时，通常想要同步测试脚本以使它们在预定义的时间启动。测试脚本可以修改为通过将希望的启动时间与系统时间相比较而在一个特定时间启动。在连网的系统中，每个测试工作站将通过该网络共享同一时钟。在以下示例中（来自使用 BASIC
    编写的一个脚本），在脚本的开头处插入了语句以暂挂该脚本的执行，直到达到所需的时间。
</p>
<p class="example">
    <code>InputFile$ = "TIME.DAT"<br />
    Open InputFile$ For Input As 1<br />
    Input #1, StartTime$<br />
    Close #1<br />
    Do While TimeValue(StartTime$) &gt; Time<br />
    &nbsp;&nbsp;&nbsp;DoEvents<br />
    Loop</code><br />
    [启动脚本]
</p>
<p>
    在此示例中，所需的启动时间存储在一个文件中。这允许可以在不更改测试脚本的情况下更改启动时间。该时间在称为 <code>StartTime$</code> 的变量中读取和存储。<code>Do While</code>
    循环一直持续，直至启动时间到达。<code>DoEvents</code> 语句非常重要：它允许在测试脚本暂挂并等待启动时执行后台任务。如果没有 <code>DoEvents</code> 语句，则在到达启动时间之前系统无响应。
</p>
<h3>
    <a id="TestingAndDebuggingTestScripts" name="TestingAndDebuggingTestScripts">测试和调试测试脚本</a> <a key="测试脚本（test script）" text="测试和调试测试脚本" name="XE_test_script__testing_and_debugging_test_scripts" id="XE_test_script__testing_and_debugging_test_scripts" class="index"></a>
</h3>
<p>
    当新记录的测试脚本在记录它们的同一软件上执行时，应该没有任何错误。环境和软件与其记录时完全相同。可能存在测试脚本不能成功运行的情况。测试测试脚本会发现这些情况，并允许在这些脚本用于实际测试之前得到纠正。下面讨论了两种典型的问题：
</p>
<ul>
    <li>
        在用户界面中用于选择项的方法中的模糊性可以使测试脚本在回放时操作不同。例如，由项的文本（或标题）识别的两个项可能具有相同的文本。当执行该脚本时，将有模糊性。
    </li>
    <li>
        特定于测试运行／会话的数据被记录（即，指针、日期／时间戳记或其他某个系统生成的数据值），但在回放时不同。
    </li>
</ul>
<p>
    记录和回放中的计时不同可能会导致问题。记录测试脚本的过程本质上比执行它的过程要慢。有时，这种时间差别会导致测试脚本的运行超过软件的运行。在这些情况下，可以插入等待状态以将测试脚本的速度降为软件的速度。
</p><br />
<br /></td>
</tr>
</table>
</div>
<table class="copyright" border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="copyright">Copyright &copy; 2008 版权所有 东软集团股份有限公司&nbsp; 联系邮箱:<a href="mailto:tcoe@neusoft.com">tcoe@neusoft.com</a></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
<script type="text/javascript" language="JavaScript">
				contentPage.onload();
			</script>
</html>
